import { lazyReportBatch } from "../report";

/**
 * 前端错误监控主函数，包含三类错误捕获：
 * 1. 资源加载错误（js/css/img等）
 * 2. JavaScript运行时错误
 * 3. 未处理的Promise拒绝（async/await错误）
 *
 * @function error
 * @returns {void}
 */
export default function error() {
  // 资源加载错误监控（事件捕获阶段监听）
  window.addEventListener(
    "error",
    function (e) {
      const target = e.target;
      // 过滤非资源加载错误（如JS运行时错误）
      if (!target) {
        return;
      }

      // 仅处理带资源路径的加载错误（src/href属性）
      if (target.src || target.href) {
        const reportData = {
          type: "error",
          subType: "resource", // 错误子类型：资源加载错误
          url: target.src || target.href, // 资源路径
          html: target.outerHTML, // 出错元素的完整HTML
          pageUrl: window.location.href, // 当前页面URL
          paths: e.path, // 事件冒泡路径
          startTime: performance.now(), // 错误发生时间戳
        };
        // todo 上报错误信息
        lazyReportBatch(reportData);
      }
    },
    true // 使用捕获模式监听错误
  );

  /**
   * JavaScript运行时错误处理函数
   *
   * @param {string} msg - 错误信息
   * @param {string} url - 出错脚本URL
   * @param {number} lineNo - 错误行号
   * @param {number} columnNo - 错误列号
   * @param {Error} error - Error对象
   */
  window.onerror = function (msg, url, lineNo, columnNo, error) {
    const reportData = {
      type: "error",
      subType: "js", // 错误子类型：JS运行时错误
      msg, // 原始错误信息
      url, // 出错文件路径
      lineNo, // 错误行号
      columnNo, // 错误列号
      error, // Error对象实例
      stack: error.stack, // 完整错误堆栈
      pageUrl: window.location.href, // 当前页面URL
      startTime: performance.now(), // 错误发生时间戳
    };
    // todo 上报
    lazyReportBatch(reportData);
  };

  // Promise未处理拒绝监控
  window.addEventListener("unhandledrejection", function (e) {
    const reportData = {
      type: "error",
      subType: "promise", // 错误子类型：Promise错误
      msg: e.reason, // 拒绝原因（通常为Error对象）
      pageUrl: window.location.href, // 当前页面URL
      startTime: performance.now(), // 错误发生时间戳
    };
    // todo 上报
    lazyReportBatch(reportData);
  });
}
